package com.xyw.code.platform.webapps.event;

import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.xyw.code.bus.common.entity.form.SendMessageForm;
import com.xyw.code.bus.common.feign.SendMessageRemoteApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

/**
 * Created with IntelliJ IDEA.
 * User: xuyiwei
 * Date: 2020/2/20
 * Time: 下午8:47
 * Email: 1328312923@qq.com
 * Description: No Description
 **/
@Component
@Slf4j
public class BusReceiver {

    @Autowired
    private SendMessageRemoteApi sendMessageRemoteApi;

    @RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue(value = "boot.queue2", durable = "true"),
                    exchange = @Exchange(value = "BOOT-EXCHANGE-2", type = "topic", durable = "true", ignoreDeclarationExceptions = "true"),
                    key = "boot1.*"
            )
    )
    @RabbitHandler
    public void process7(Message message, Channel channel) throws Exception {
        // 模拟消费者代码异常，这种情况必须在catch块设置重试次数（也可以在配置文件中全局设置重试次数，当然百度的方案都不行，所以我没成功过），防止死循环
        // catch块中重试可用redis的自增来做计数器，从而控制重试次数
        try {
            System.out.println(new String(message.getBody(), StandardCharsets.UTF_8));
            int i = 1/0;
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            //就算失败也要签收消息 因为所有消息都在重新发送的时候处理了
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            String correlationId = (String) message.getMessageProperties().getHeaders().get("spring_returned_message_correlation");
            System.out.println("消息投放失败:" +  JSONObject.toJSONString(message.getMessageProperties()));
            sendMessageRemoteApi.dealFail(
                    SendMessageForm.build(
                            new String(message.getBody()),
                            message.getMessageProperties().getReceivedExchange(),
                            message.getMessageProperties().getReceivedRoutingKey(),
                            correlationId,
                            e.getMessage()
                    ));
        }
    }

}
